import {messages} from "share/common";
import React from 'react';
import {connect} from 'react-redux'
import { Modal, message, Button, Input, Row, Col, Card, Checkbox, Tree, Switch, Spin } from 'antd'
const Search = Input.Search;
const CheckboxGroup = Checkbox.Group;
const TreeNode = Tree.TreeNode;
import httpFetch from 'share/httpFetch'
import debounce from 'lodash.debounce';
import config from 'config'
import 'styles/components/select-contract.scss'

class SelectDepartment extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      toData: [],  //待选区的数据
      useData: [], //使用区的数据
      useDepartment: [], //使用区显示的数据
      expandedKey: [],
      autoExpandParent: true,
      selectedKeys: [],
      loading: false,
      toSearchText: '',
      useSearchText: '',
      toSelectList: [],  //待选区选中的列表
      useSelectList: [],  //使用区选中的列表
      isRelated: false //关联开关
    };
    this.onSearch = debounce(this.onSearch, 250);
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps.visible && nextProps.visible !== this.props.visible) {
      let temp = [];
      let useTemp = [];
      nextProps.selectedData && nextProps.selectedData.map(item => {
        temp.push(JSON.stringify({
          id: item.value,
          path: item.label
        }));
        useTemp.push({
          label: item.label,
          value: item.value
        });
      });
      this.setState({ useData: nextProps.selectedData, toSearchText: '', useSearchText: '', toSelectList: temp, useDepartment: useTemp }, () => {
        this.getList();
      });
    }
  }

  useSearch = (value) => {
    const { useData } = this.state;
    let temp = [];
    useData.map(item => {
      if(value ? ~item.label.indexOf(value) : true){
        temp.push({
          value: item.value,
          label: item.label
        });
      }
    });
    this.setState({ useDepartment: temp, useSearchText: value });
  };

  renderTreeNodes = (data) => {
    return data.map((item) => {
      if (item.children) {
        return (
          <TreeNode title={item.title} key={item.key} dataRef={item}>
            {this.renderTreeNodes(item.children)}
          </TreeNode>
        );
      }
      return <TreeNode {...item} dataRef={item} />;
    });
  };

  onLoadData = (treeNode) => {
    const { company, isNeedCompany } = this.props;
    return new Promise((resolve) => {
      if (treeNode.props.children) {
        resolve(treeNode.props.children);
        return;
      }
      let model = JSON.parse(treeNode.props.eventKey);
      let url = `${config.baseUrl}/api/department/child/${model.id}?flag=1002`;
      if (isNeedCompany) {
        url += `&companyId=${company.id}`;
      }
      httpFetch.get(url).then(res => {
        let temp = [];
        res.data = res.data || [];
        res.data.map(item => {
          let obj = {
            id: this.props.mode === "oid" ? item.departmentOID : item.id,
            path: item.path
          };
          let jsonStr = JSON.stringify(obj);
          temp.push({ title: item.name, key: jsonStr, isLeaf: !item.hasChildrenDepartments, departmentId: item.id });
        });
        treeNode.props.dataRef.children = temp;
        this.setState({
          toSelectList: this.state.toSelectList //加个异步 不然会加载不出来
        });
        resolve(res);
      })
    });
  };

  getList = () => {
    const { company, isNeedCompany } = this.props;
    this.setState({ loading: true });
    let url = `${config.baseUrl}/api/departments/root/v2?flag=1002`;
    if (isNeedCompany) {
      url += `&companyId=${company.id}`;
    }
    httpFetch.get(url).then(res => {
      if (res.data && res.data.length) {
        let temp = [];
        res.data.map(item => {
          let obj = {
            id: this.props.mode === "oid" ? item.departmentOID : item.id,
            path: item.path
          };
          let jsonStr = JSON.stringify(obj);
          temp.push({ title: item.name, key: jsonStr, isLeaf: !item.hasChildrenDepartments, departmentId: item.id });
        });
        this.setState({ toData: temp, loading: false });
      }
      else {
        this.setState({ toData: [], loading: false });
      }
    }).catch(() => {
      message.error(messages('components.key761')/*系统异常*/);
      this.setState({ loading: false });
    })
  };

  onCheck = (values,e) => {
    const { company, isNeedCompany } = this.props;
    const { isRelated } = this.state;
    if(isRelated && !e.node.props.isLeaf){
      this.setState({loading: true});
      let url = `${config.baseUrl}/api/department/cascade?departmentId=${e.node.props.dataRef.departmentId}&status=101&includeChild=true`;
      if (isNeedCompany) {
        url += `&companyId=${company.id}`;
      }
      httpFetch.get(url).then(res => {
        let departmentList = this.getDepartmentList([res.data]);
        departmentList.map(item => {
          if(e.checked){
            values.checked.findIndex(o => JSON.parse(o).id === item.id) === -1 && values.checked.push(JSON.stringify(item));
          } else {
            let index = values.checked.findIndex(o => JSON.parse(o).id === item.id);
            values.checked.splice(index, index >= 0 ? 1 : 0);
          }
        });
        this.setState({ toSelectList: values.checked, loading: false });
      }).catch(e => {
        this.setState({loading: false});
        message.error(e.response.data.message);
      })
    }else{
      this.setState({ toSelectList: values.checked });
    }
  };

  getDepartmentList = (arr, res = []) => {
    arr.map(item => {
      let obj = {
        id: this.props.mode === 'oid' ? item.departmentOID : item.id,
        path: item.path
      };
      res.push(obj);
      if(item.children && item.children.length > 0){
        this.getDepartmentList(item.children, res);
      }
    });
    return res;
  };

  handleOk = () => {
    this.setState({expandedKey: []},() => {
      this.props.onOk({
        checkedKeys: this.state.useData.concat([])
      });
    });
  };

  handleCancel = () => {
    this.setState({expandedKey: []},() => {
      this.props.onCancel();
    });
  };

  addToUse = () => {
    const { useData, toSelectList, useDepartment } = this.state;
    toSelectList.map(item => {
      let model = JSON.parse(item);
      if (useData.findIndex(o => o.value == model.id) >= 0)
        return;
      useData.push({
        label: model.path,
        value: model.id,
      });
      useDepartment.push({
        label: model.path,
        value: model.id
      })
    });
    this.setState({ useData: useData.concat([]), useDepartment: useDepartment.concat([]), useSearchText: '' });
  };

  removeFromUse = () => {
    let { useData, useDepartment, useSelectList } = this.state;
    useSelectList.map(item => {
      useData.splice(useData.findIndex(o => o.value == item), 1);
      useDepartment.splice(useDepartment.findIndex(o => o.value == item), 1);
    });
    this.setState({ useData: useData.concat([]), useSelectList: [], useDepartment: useDepartment.concat([]) });
  };

  useCheckboxChange = (values) => {
    this.setState({ useSelectList: values });
  };

  onSearch = (value) => {
    const { company, isNeedCompany } = this.props;
    if (!value) {
      this.getList();
      return;
    }
    this.setState({ loading: true });
    let url = `${config.baseUrl}/api/department/tenant/keyword/v2?status=101&keyword=${encodeURIComponent(value)}`;
    if (isNeedCompany) {
      url += `&companyId=${company.id}`;
    }
    httpFetch.get(url).then(res => {
      if (res.data && res.data.length) {
        let temp = [];
        res.data = res.data || [];
        res.data.map(item => {
          let obj = {
            id: this.props.mode === "oid" ? item.departmentOID : item.id,
            path: item.path
          };
          let jsonStr = JSON.stringify(obj);
          temp.push({ title: item.name, key: jsonStr, isLeaf: !item.hasChildrenDepartments, departmentId: item.id });
        });
        this.setState({ toData: temp, loading: false });
      }
      else {
        this.setState({ toData: [], loading: false });
      }
    })
  };

  onChange = (value) => {
    this.setState({ toSearchText: value },() => {
      this.onSearch(value);
    });
  };

  handleExpand = (expandedKeys,e) => {
    const { expandedKey } = this.state;
    if(e.expanded){
      expandedKey.push(e.node.props.eventKey);
    }else{
      expandedKey.map((item,index) => {
        item === e.node.props.eventKey && expandedKey.splice(index,1);
      })
    }
    this.setState({expandedKey});
  };

  render() {
    const { visible, afterClose, related } = this.props;
    const { toData, useSelectList, toSelectList, useDepartment, toSearchText, useSearchText, loading, expandedKey } = this.state;
    return (
      <Modal title={messages('components.key551')/*选择部门*/} visible={visible} onCancel={this.handleCancel} afterClose={afterClose} width={"70%"} onOk={this.handleOk} className="list-selector select-department select-employee-group ">
        <Row gutter={10} style={{ height: "100%" }}>
          <Col span={10} style={{ height: "100%" }}>
            <Card title={<div>{messages('components.key553')/*待选区*/}
              {
                related && <span className={'title-switch'}>
                  <Switch  onChange={value => this.setState({isRelated:value})}/>
                  <span className={'title-label'}>{messages('components.key808')/*是否包含子部门*/}</span>
                </span>
              }
            </div>}>
              <Spin spinning={loading}>
                <Search style={{ marginBottom: 8 }}
                        value={toSearchText}
                        placeholder={messages('common.please.enter')}
                        onChange={(e) => this.onChange(e.target.value)} />
                <Tree checkable
                      defaultExpandParent={false}
                      expandedKeys={expandedKey}
                      loadData={this.onLoadData}
                      onCheck={this.onCheck}
                      onExpand={this.handleExpand}
                      checkStrictly={this.props.checkStrictly}
                      defaultCheckedKeys={toSelectList}>
                  {this.renderTreeNodes(toData)}
                </Tree>
              </Spin>
            </Card>
          </Col>
          <Col span={4} style={{ height: "100%" }}>
            <div style={{ height: "100%", display: "flex", alignItems: "center", justifyContent: "center" }}>
              <div>
                <Button disabled={!toSelectList.length} onClick={this.addToUse} size="small" type="primary">{messages('components.key532'/*加入使用*/)}&gt;</Button>
                <br />
                <Button disabled={!useSelectList.length} onClick={this.removeFromUse} style={{ marginTop: 15 }} size="small" type="primary">&lt;{messages('components.key533'/*回到待选*/)}</Button>
              </div>
            </div>
          </Col>
          <Col style={{ height: "100%" }} span={10}>
            <Card title={messages('components.key534'/*使用列表*/)}>
              <Search
                value={useSearchText}
                placeholder={messages('common.please.enter')/*请输入*/}
                onChange={(e) => this.useSearch(e.target.value)}
              />
              <div style={{ margin: "10px 15px" }}>
                <CheckboxGroup value={useSelectList} onChange={this.useCheckboxChange} options={useDepartment}/>
              </div>
            </Card>
          </Col>
        </Row>
      </Modal >
    );
  }
}

function mapStateToProps(state) {
  return {
    company: state.login.company
  }
}

SelectDepartment.propTypes = {
  onCancel: React.PropTypes.func,
  afterClose: React.PropTypes.func,
  visible: React.PropTypes.bool,  //对话框是否可见
  onOk: React.PropTypes.func,  //点击OK后的回调，当有选择的值时会返回一个数组 [{label:"",value:""}]
  selectedData: React.PropTypes.array,  //默认选择的值id数组
  mode: React.PropTypes.string,          //模式 “oid” “id" 默认为id模式
  isNeedCompany: React.PropTypes.bool, //所用到的接口是否需要传companyId，如果传了且配置部门关联公司，则后台会返回对应公司下的部门
  checkStrictly:React.PropTypes.bool,//是否关联子部门，默认不关联
  related: React.PropTypes.bool
};

SelectDepartment.defaultProps = {
  mode: "id",
  isNeedCompany: false,
  checkStrictly: true,
  related: false
};

export default connect(mapStateToProps)(SelectDepartment)
